<?php

namespace app\services;

use app\payment\PayFactory;
use app\traits\Page;
use plugin\admin\app\model\Order;
use plugin\admin\app\model\User;
use plugin\admin\app\model\UserHall;
use plugin\admin\app\model\UserPropertyLog;
use plugin\admin\app\model\UserSurname;
use plugin\admin\app\model\UserWorshipProductLog;
use plugin\admin\app\model\WorshipAncestor;
use plugin\admin\app\model\WorshipCategory;
use plugin\admin\app\model\WorshipProduct;
use plugin\admin\app\model\WorshipSurname;
use plugin\admin\app\model\WorshipSurnameCategory;
use plugin\admin\app\model\WorshipSurnameHall;

class WorshipService
{
    public static function categories()
    {
        $list = WorshipCategory::orderBy('sort')->get()->toArray();

        foreach ($list as $key=>$item) {
            $list[$key]['thumb'] = full_url($item['thumb']);
        }

        return $list;
    }

    public static function ancestors($page, $length = 10, $categoryId = 0, $name = '')
    {
        $query = WorshipAncestor::select(['id', 'name', 'thumb']);

        if ($categoryId) {
            $query = $query->where('category_id', $categoryId);
        }

        if ($name) {
            $query = $query->where('name', 'like', "%{$name}%");
        }

        $offset = ($page - 1) * $length;

        $count = (clone $query)->count();
        $ancestors = $query->offset($offset)->limit($length)->orderBy('sort')->get()->toArray();

        foreach ($ancestors as $key=>$ancestor) {
            $ancestors[$key]['thumb'] = full_url($ancestor['thumb']);
        }

        return Page::wrap($count, $page, $length, $ancestors);
    }

    public static function addSurname($data)
    {
        $config = ConfigService::get('worship');

        $payWay = $data['pay_way'] ?? 'medal';
        switch ($payWay) {
            default:
            case 'kindness':
                $price = $config['add_surname_kindness_amount'];
                break;
            case 'medal':
                $price = $config['add_surname_amount'];
                break;
            case 'gd':
                $price = $config['add_surname_gd_amount'];
                break;
            case 'fu':
                $price = $config['add_surname_fu_amount'];
                break;
        }

        $id = WorshipSurname::insertGetId([
            'category_id' => $data['category_id'],
            'user_id' => get_user_id(),
            'name' => $data['name'],
            'desc' => $data['desc'],
            'dynasty' => $data['dynasty'],
            'thumb' => $data['thumb'],
            'is_enable' => 1,
        ]);

        if ($data['is_up']) {
            self::topSurname($data['category_id'], $id);
        }

        PropertyService::reduce(get_user_id(), $payWay, $price, UserPropertyLog::ADD_SURNAME);

    }

    public static function topSurname($categoryId, $surnameId)
    {
        if ($res = UserSurname::where('category_id', $categoryId)->where('user_id', get_user_id())->first()) {
            $res->surname_id = $surnameId;
            $res->save();
        } else {
            UserSurname::insert([
                'category_id' => $categoryId,
                'user_id' => get_user_id(),
                'surname_id' => $surnameId
            ]);
        }
    }

    public static function ancestorDetail($id)
    {
        $detail = WorshipAncestor::select(['id', 'name', 'thumb', 'desc'])->where('id', $id)->first();

        $detail['thumb'] = full_url($detail['thumb']);
        return $detail;
    }

    public static function surnameCategories($page, $length = 10, $name = '')
    {
        $query = WorshipSurnameCategory::select(['id', 'name', 'thumb', 'desc']);

        if ($name) {
            $query = $query->where('name', 'like', "%{$name}%");
        }

        $offset = ($page - 1) * $length;

        $count = (clone $query)->count();
        $list = $query->offset($offset)->limit($length)->orderBy('sort')->get()->toArray();

        $surnames = WorshipSurname::where('is_default', 1)->get()->toArray();
        $surnames = array_combine(
            array_column($surnames, 'category_id'),
            array_values($surnames)
        );

        foreach ($list as $key=>$item) {
            $list[$key]['thumb'] = full_url($item['thumb']);
            $list[$key]['default_surname_id'] = $surnames[$item['id'] ?? 0]['id'] ?? 0;
        }

        return Page::wrap($count, $page, $length, $list);
    }

    public static function surnames($page, $length, $categoryId)
    {
        $offset = ($page - 1) * $length;

        $userSurname = UserSurname::where('category_id', $categoryId)->where('user_id', get_user_id())->first();

        $query = WorshipSurname::select(['id', 'name', 'thumb', 'desc', 'is_default'])->where('is_enable', 1)->where('category_id', $categoryId)->where('user_id', get_user_id());

        if ($userSurname) {
            $query = $query->where('id', '<>', $userSurname['surname_id']);
        }

        $count = (clone $query)->count();
        $list = $query->offset($offset)->limit($length)->get()->toArray();

        foreach ($list as $key=>$item) {
            $list[$key]['thumb'] = full_url($item['thumb']);
        }

        $surname = self::getTopSurname($categoryId);

        if ($surname && $page == 1) {
            array_unshift($list, $surname);
        }

        return Page::wrap($count, $page, $length, $list);
    }

    public static function getTopSurname($categoryId)
    {
        $userSurname = UserSurname::where('category_id', $categoryId)->where('user_id', get_user_id())->first();

        if ($userSurname) {
            $data = WorshipSurname::select(['id', 'name', 'thumb', 'desc'])->where('id', $userSurname['surname_id'])->first();

            if ($data) {
                $data['thumb'] = full_url($data['thumb']);

                $data['is_top'] = true;

                return $data;
            }

        }

        return [];
    }

    public static function surnameDetail($id)
    {
        $detail = WorshipSurname::select(['id', 'name', 'thumb', 'desc'])->where('id', $id)->first();

        $detail['thumb'] = full_url($detail['thumb']);
        return $detail;
    }

    public static function transferToGD($count, $payWay)
    {
        $user = User::find(get_user_id());

        $orderNo = OrderService::generateOrderNo();
        Order::insert([
            'user_id' => get_user_id(),
            'order_no' => $orderNo,
            'price' => $count,
            'pay_way' => $payWay,
            'remark' => $data['remark'] ?? '',
            'status' => Order::STATUS_WAITING_PAY,
            'created_time' => date('Y-m-d H:i:s'),
            'type' => Order::TYPE_GD
        ]);

        $result = PayFactory::create($payWay)->setData(['order_no' => $orderNo, 'total_amount' => $count, 'source' => UserPropertyLog::PAY_BUY_MEDAL, 'openid' => $user['open_id']])->pay();

        if ($payWay != PayFactory::WECHAT) {
            self::paySuccess(get_user_id(), $orderNo);
        }

        return $result;
    }

    public static function paySuccess($userId, $orderNo)
    {
        $order = Order::where('order_no', $orderNo)->first();

        $order->status = Order::STATUS_FINISH;
        $order->pay_time = date('Y-m-d H:i:s');
        $order->save();

        PropertyService::add($order['user_id'], PayFactory::GD, $order['price'], UserPropertyLog::BUY_GD);
    }

    public static function addHall($data)
    {
        $data['user_id'] = get_user_id();

        if ($data['images']) {
            $data['images'] = json_encode($data['images'], JSON_UNESCAPED_UNICODE);
        }

        self::checkIsMatchCondition($data['category_id']);

        $data['is_enable'] = 1;
        $data['created_time'] = date('Y-m-d H:i:s');
        $hallId = WorshipSurnameHall::insertGetId($data);

        if ($data['is_up']) {
            self::topHall($data['category_id'], $hallId);
        }
    }

    public static function checkIsMatchCondition($categoryId)
    {
        $surname = WorshipSurname::where('category_id', $categoryId)->where('user_id', get_user_id())->first();

        if (!$surname) {
            throw new \Exception('请先发布该姓氏先祖');
        }
    }

    public static function topHall($categoryId, $hallId)
    {
        if ($res = UserHall::where('user_id', get_user_id())->where('category_id', $categoryId)->first()) {
            $res->hall_id = $hallId;
            $res->save();
        } else {
            UserHall::insert(['user_id' => get_user_id(), 'hall_id' => $hallId, 'category_id' => $categoryId]);
        }
    }

    public static function updateHall($data)
    {
        $data['user_id'] = get_user_id();

        if ($data['images']) {
            $data['images'] = json_encode($data['images'], JSON_UNESCAPED_UNICODE);
        }

        WorshipSurnameHall::where('id', $data['id'])->update($data);

        $exists = UserHall::where('user_id', get_user_id())->where('hall_id', $data['id'])->where('category_id', $data['category_id'])->count() > 0;
        if ($data['is_up']) {
            if (!$exists) {
                UserHall::insert(['user_id' => get_user_id(), 'hall_id' => $data['id'], 'category_id' => $data['category_id']]);
            }
        } else {
            if ($exists) {
                UserHall::where('user_id', get_user_id())->where('hall_id', $data['id'])->where('category_id', $data['category_id'])->delete();
            }
        }
    }

    public static function getTopHall($categoryId)
    {
        $userHall = UserHall::where('category_id', $categoryId)->where('user_id', get_user_id())->first();

        if ($userHall) {
            $data = WorshipSurnameHall::select(['id', 'name', 'thumb', 'nick'])->where('id', $userHall['hall_id'])->first();

            if ($data) {
                $data['thumb'] = full_url($data['thumb']);

                return $data;
            }

        }

        return [];
    }

    public static function halls($page, $length, $categoryId)
    {
        $offset = ($page - 1) * $length;

//        $userHall = UserHall::where('category_id', $categoryId)->where('user_id', get_user_id())->first();

        $query = WorshipSurnameHall::select(['id', 'name', 'thumb', 'nick'])->where('is_enable', 1)->where('category_id', $categoryId);

//        if ($userHall) {
//            $query = $query->where('id', '<>', $userHall['hall_id']);
//        }

        $count = (clone $query)->count();
        $list = $query->offset($offset)->limit($length)->get()->toArray();

        foreach ($list as $key=>$item) {
            $list[$key]['thumb'] = full_url($item['thumb']);
        }

        return Page::wrap($count, $page, $length, $list);
    }

    public static function hallDetail($id)
    {
        $detail = WorshipSurnameHall::select(['id', 'user_id', 'name', 'thumb', 'nick', 'images', 'province', 'city', 'district', 'longitude', 'latitude', 'leader', 'address', 'desc', 'mobile', 'is_up'])->where('id', $id)->first();

        if (!$detail) {
            throw new \Exception('不存在的宗祠');
        }

        $detail = $detail->toArray();

        $detail['thumb'] = full_url($detail['thumb']);
        $detail['images'] = json_decode($detail['images'], true);

        foreach ($detail['images'] as $key=>$image) {
            $detail['images'][$key] = full_url($image);
        }
        return $detail;
    }

    public static function products($type)
    {
        $products = WorshipProduct::where('type', $type)->get()->toArray();

        foreach ($products as $key=>$product) {
            $products[$key]['thumb'] = full_url($product['thumb']);
        }

        return $products;
    }

    public static function worship($type, $targetId, $productId, $count)
    {
        if ($productId != 0) {
            $product = WorshipProduct::where('id', $productId)->first();
            PayFactory::create(PayFactory::KINDNESS)->setData(['total_amount' => $product['price'] * $count, 'source' => UserPropertyLog::WORSHIP])->pay();
        }

        // 上香获取孝心
        $config = ConfigService::get('worship');

        $logCount = UserWorshipProductLog::where('user_id', get_user_id())->where('product_id', 0)->whereBetween('created_time', [date('Y-m-d 00:00:00'), date('Y-m-d 23:59:59')])->count();

        if ($productId == 0 && $logCount >= $config['filial_piety_count']) {
            throw new \Exception('今日总上香次数已达上限');
        }

        $eachLogCount = UserWorshipProductLog::where('user_id', get_user_id())->where('target_id', $targetId)->where('product_id', 0)->whereBetween('created_time', [date('Y-m-d 00:00:00'), date('Y-m-d 23:59:59')])->count();

        if ($productId == 0 && $eachLogCount >= $config['each_filial_piety_count']) {
            throw new \Exception('今日该先祖上香次数已达上限');
        }

        UserWorshipProductLog::insert([
            'user_id' => get_user_id(),
            'type' => $type,
            'target_id' => $targetId,
            'product_id' => $productId,
            'count' => $count,
            'created_time' => date('Y-m-d H:i:s')
        ]);

        if ($productId == 0) {

            PropertyService::add(get_user_id(), PayFactory::FILIAL_PIETY, $config['filial_piety_amount'] ?? 1, UserPropertyLog::SX);
        }
    }

    public static function worshipList($page, $length, $type, $targetId)
    {
        $offset = ($page - 1) * $length;
        $query = UserWorshipProductLog::select([
            'user_id',
            'product_id',
            'count',
            'created_time'
        ])->where('type', $type)->where('target_id', $targetId);

        $count = (clone $query)->count();
        $logs = $query->offset($offset)->limit($length)->orderByDesc('created_time')->get()->toArray();

        $productIds = array_column($logs, 'product_id');
        $products = WorshipProduct::select(['id', 'name', 'thumb'])->whereIn('id', $productIds)->get()->toArray();
        $products = array_combine(
            array_column($products, 'id'),
            array_values($products)
        );

        $products[0] = [
            'id' => 0,
            'name' => '上香',
            'thumb' => ''
        ];

        $userIds = array_column($logs, 'user_id');
        $users = User::select(['id', 'nickname', 'avatar'])->whereIn('id', $userIds)->get()->toArray();
        $users = array_combine(
            array_column($users, 'id'),
            array_values($users)
        );

        foreach ($logs as $key=>$log) {
            $logs[$key]['product_info'] = $products[$log['product_id']];
            $logs[$key]['user_info'] = $users[$log['user_id']];
        }

        return Page::wrap($count, $page, $length, $logs);
    }
}